package jinyilw.swing.visuals;

import jinyilw.common.Operator;
import jinyilw.swing.Alignment;
import jinyilw.swing.ColorTools;
import jinyilw.swing.DragCompUtils;
import jinyilw.swing.ResourceManager;
import jinyilw.swing.ScreenTools;
import jinyilw.swing.rlaf.UITools;
import jinyilw.swing.rlaf.theme.UIData;
import jinyilw.swing.visuals.Icomp.IRichTextLabel;
import jinyilw.swing.visuals.comp.ActIconComp;
import jinyilw.swing.visuals.label.ActionLabel;
import jinyilw.swing.visuals.panel.FlowPanel;

import javax.swing.JDialog;
import javax.swing.JMenuBar;
import javax.swing.JRootPane;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.Dialog;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Frame;
import java.awt.GraphicsConfiguration;
import java.awt.Window;
import java.awt.event.MouseListener;
import java.awt.event.WindowListener;
import java.awt.geom.RoundRectangle2D;

public class TransDialog extends JDialog
{
	private static final long serialVersionUID = -3604680178901370659L;
	private TransRootPane rootPane;
	private Container backgroundPanel;
	private final FlowPanel actionPanel = new FlowPanel();
	private final ActIconComp closeAction = new ActIconComp();
	private Container contentPanel = new Container();
	private ActionLabel icon;
	private IRichTextLabel title;
	private Container menu;
	private int titleHeight, menuHeight = 0;
	private Font titleFont;
	private Color titleColor;
	private final Alignment titleAlign = Alignment.CENTER;
	private int section = 0;
	private Dimension maxDimension;
	private Dimension defaultDimension;
	protected boolean rounded = true;
	boolean disposeUninstallTheme = false;
	Dimension preferredSize;

	public TransDialog()
	{
		initGUI();
	}

	public TransDialog(Frame owner)
	{
		super(owner);
		initGUI();
	}

	public TransDialog(Dialog owner)
	{
		super(owner);
		initGUI();
	}

	public TransDialog(Window owner)
	{
		super(owner);
		initGUI();
	}

	public TransDialog(Frame owner, boolean modal)
	{
		super(owner, modal);
		initGUI();
	}

	public TransDialog(Frame owner, String title)
	{
		super(owner, title);
		initGUI();
	}

	public TransDialog(Dialog owner, boolean modal)
	{
		super(owner, modal);
		initGUI();
	}

	public TransDialog(Dialog owner, String title)
	{
		super(owner, title);
		initGUI();
	}

	public TransDialog(Window owner, ModalityType modalityType)
	{
		super(owner, modalityType);
		initGUI();
	}

	public TransDialog(Window owner, String title)
	{
		super(owner, title);
		initGUI();
	}

	public TransDialog(Frame owner, String title, boolean modal)
	{
		super(owner, title, modal);
		initGUI();
	}

	public TransDialog(Dialog owner, String title, boolean modal)
	{
		super(owner, title, modal);
		initGUI();
	}

	public TransDialog(Window owner, String title, ModalityType modalityType)
	{
		super(owner, title, modalityType);
		initGUI();
	}

	public TransDialog(Frame owner, String title, boolean modal,
			GraphicsConfiguration gc)
	{
		super(owner, title, modal, gc);
		initGUI();
	}

	public TransDialog(Dialog owner, String title, boolean modal,
			GraphicsConfiguration gc)
	{
		super(owner, title, modal, gc);
		initGUI();
	}

	public TransDialog(Window owner, String title, ModalityType modalityType,
			GraphicsConfiguration gc)
	{
		super(owner, title, modalityType, gc);
		initGUI();
	}

	private void initGUI()
	{
		JRootPane rp = getRootPane();
		if (rp instanceof TransRootPane)
			rootPane = (TransRootPane) rp;
		maxDimension = ScreenTools.getDefaultScreenSize();
		int w = (int) (maxDimension.width * 0.6);
		int h = (int) (maxDimension.height * 0.6);
		defaultDimension = new Dimension(w, h);
		setUIData(UIData.getDefaultUIData());
		backgroundPanel = super.getContentPane();
		super.setContentPane(backgroundPanel);
		backgroundPanel.setLayout(null);
		actionPanel.add(closeAction);
		backgroundPanel.add(actionPanel);
		backgroundPanel.add(contentPanel);
		contentPanel.setLayout(new BorderLayout());
		DragCompUtils.setMovable(backgroundPanel, this);
		closeAction.addClickOperator(o -> {
			WindowListener[] listeners = getWindowListeners();
			if (listeners != null)
				for (WindowListener l : listeners)
					l.windowClosing(null);
			dispose();
		});
		setTitle(getTitle());
		setBackground(ColorTools.transparentColor);
	}

	public void setContentPanel(Container container)
	{
		if (container == null || container == contentPanel)
			return;
		container.setBounds(contentPanel.getBounds());
		backgroundPanel.remove(contentPanel);
		backgroundPanel.add(container);
		backgroundPanel.validate();
		container.repaint();
		contentPanel = container;
	}

	@Override
	public void setContentPane(Container container)
	{
		setContentPanel(container);
	}

	@Override
	public Container getContentPane()
	{
		return contentPanel;
	}

	@Override
	protected JRootPane createRootPane()
	{
		return new TransRootPane(this);
	}

	@Override
	public void setBounds(int x, int y, int width, int height)
	{
		super.setBounds(x, y, width, height);
		if (width == 0 || height == 0)
			return;
		if (rounded)
			setShape(new RoundRectangle2D.Double(0, 0, width, height, 5, 5));
		updateCompLocation();
	}

	@Override
	public void setTitle(String txt)
	{
		if (txt == null)
			return;
		if (title != null && txt.equals(title.getText()))
			return;
		if (title == null)
		{
			title = new IRichTextLabel(txt, titleFont, titleColor);
			backgroundPanel.add(title);
		} else
			title.setText(txt);
		if (titleAlign == Alignment.CENTER)
		{
			title.setLocation((getWidth() - title.getWidth()) / 2,
					(titleHeight - title.getHeight()) / 2);
		} else
		{
			if (icon != null)
				title.setLocation(icon.getWidth() + 5,
						(titleHeight - title.getHeight()) / 2);
			else
				title.setLocation(5, (titleHeight - title.getHeight()) / 2);
		}
		super.setTitle(txt);
	}

	@Override
	public void setResizable(boolean b)
	{
		if (b)
		{
			if (section == 0)
				setSection(1);
			DragCompUtils.setResizeable2(backgroundPanel, this);
		}
	}

	public boolean isRounded()
	{
		return rounded;
	}

	public void setRounded(boolean b)
	{
		rounded = b;
		if (b)
			setShape(new RoundRectangle2D.Double(0, 0, getWidth(), getHeight(),
					5, 5));
		else
			setShape(null);
	}

	public void setUIData(UIData uiData)
	{
		closeAction.setActionIcon(uiData.dialogUI.closeIcon,
				uiData.dialogUI.closeIcon1);
		titleHeight = uiData.dialogUI.titleHeight;
		titleFont = uiData.dialogUI.titleFont;
		titleColor = uiData.dialogUI.titleColor;
	}

	@Override
	public synchronized void addMouseListener(MouseListener l)
	{
		super.addMouseListener(l);
		backgroundPanel.addMouseListener(l);
	}

	public void addCloseOperator(final Operator operator)
	{
		closeAction.addClickOperator(operator);
	}

	public void addMoveReleaseOperator(final Operator<?> operator)
	{
		DragCompUtils.addMoveReleaseOperator(backgroundPanel, operator);
	}

	public void setIcon(ActionLabel ic)
	{
		if (icon != null)
			backgroundPanel.remove(icon);
		icon = ic;
		if (icon != null)
		{
			backgroundPanel.add(icon);
			icon.setLocation(5, (titleHeight - icon.getHeight()) / 2);
		}
	}

	public void setIcon(Class<?> loadClass, String path)
	{
		setIcon(new ActionLabel(ResourceManager.getResLazyScaleIcon(loadClass, path), null));
	}

	public void setMenu(Container m)
	{
		if (menu == m)
			return;
		if (menu != null)
		{
			backgroundPanel.remove(menu);
			menuHeight = 0;
			setSize(getWidth(), getHeight() - menu.getHeight());
		}
		menu = m;
		if (menu != null)
		{
			menuHeight = Math.max(18, menu.getHeight());
			setSize(getWidth(), getHeight() + menuHeight);
			backgroundPanel.add(menu);
		}
	}

	@Override
	public void setJMenuBar(JMenuBar menuBar)
	{
		setMenu(menuBar);
	}

	private void updateCompLocation()
	{
		int width = getWidth();
		if (title != null)
		{
			if (titleAlign == Alignment.CENTER)
			{
				title.setLocation((width - title.getWidth()) / 2,
						(titleHeight - title.getHeight()) / 2);
			} else
			{
				if (icon != null)
					title.setLocation(icon.getWidth() + 5,
							(titleHeight - title.getHeight()) / 2);
				else
					title.setLocation(5, (titleHeight - title.getHeight()) / 2);
			}
		}
		if (menu != null && menuHeight > 0)
			menu.setBounds(0, titleHeight, width, menuHeight);
		if (contentPanel != null)
			contentPanel.setBounds(section, titleHeight + menuHeight,
					width - section * 2,
					getHeight() - titleHeight - menuHeight - section);
		if (actionPanel != null)
			actionPanel.setLocation(width - actionPanel.getWidth() - 1, 0);
	}

	public void setTitleHeight(int h)
	{
		if (h == titleHeight)
			return;
		titleHeight = h;
		if (icon != null)
			icon.setLocation(5, (titleHeight - icon.getHeight()) / 2);
		updateCompLocation();
	}

	public int getTitleHeight()
	{
		return titleHeight;
	}

	public void setTitleColor(Color color)
	{
		if (color == null || titleColor.equals(color))
			return;
		titleColor = color;
		if (title != null)
			title.setForeground(color);
	}

	public void setTitleFont(Font font)
	{
		if (font == null || titleFont.equals(font))
			return;
		titleFont = font;
		if (title != null)
			title.setFont(font);
	}

	public void setSection(int n)
	{
		if (n == section)
			return;
		section = n;
		contentPanel.setBounds(section, titleHeight, getWidth() - 2 * section,
				getHeight() - titleHeight - menuHeight - section);
	}

	public int getSection()
	{
		return section;
	}

	public void setMaxDimension(Dimension d)
	{
		maxDimension = d;
	}

	public void setDefaultDimension(Dimension d)
	{
		defaultDimension = d;
	}

	public void setDefaultDimensionRatio(double wr, double hr)
	{
		int w = (int) (maxDimension.width * wr);
		int h = (int) (maxDimension.height * hr);
		defaultDimension = new Dimension(w, h);
	}

	public void defaultSize()
	{
		setSize(defaultDimension);
	}

	public void maxSize()
	{
		setSize(maxDimension);
	}

	@Override
	public Dimension getPreferredSize()
	{
		if (!(isPreferredSizeSet() || isValid()))
		{
			synchronized (getTreeLock())
			{
				preferredSize = contentPanel.getPreferredSize();
				preferredSize.height += (titleHeight + menuHeight + section);
				preferredSize.width += section * 2;
			}
		}
		return preferredSize;
	}

	@Override
	public void dispose()
	{
		super.dispose();
		if (disposeUninstallTheme)
			UITools.uninstallTheme(this);
	}

	public void setDisposeToUninstallTheme(boolean b)
	{
		disposeUninstallTheme = b;
	}

	public void makeCustom()
	{
		UITools.uninstallTheme(this);
	}

	public void setBGOpacity(int opacity)
	{
		if (rootPane != null)
			rootPane.setColorOpacity(opacity);
	}

	public void setWindowAlpha(float alpha)
	{
		if (rootPane != null)
			rootPane.setAlpha(alpha);
	}
}
